import axios from 'axios';

interface UploadProgress {
  loaded: number;
  total: number;
  percentage: number;
}

interface UploadOptions {
  chunkSize?: number; // 分片大小，默认1MB
  onProgress?: (progress: UploadProgress) => void;
  onError?: (error: Error) => void;
  onSuccess?: (response: any) => void;
}

const DEFAULT_CHUNK_SIZE = 1024 * 1024; // 1MB

export class FileUploader {
  private file: File;
  private options: UploadOptions;
  private chunkSize: number;
  private currentChunk: number = 0;
  private totalChunks: number = 0;
  private fileId: string = '';
  private isUploading: boolean = false;
  private isPaused: boolean = false;

  constructor(file: File, options: UploadOptions = {}) {
    this.file = file;
    this.options = options;
    this.chunkSize = options.chunkSize || DEFAULT_CHUNK_SIZE;
    this.totalChunks = Math.ceil(file.size / this.chunkSize);
  }

  // 开始上传
  async startUpload(): Promise<void> {
    if (this.isUploading) return;
    this.isUploading = true;
    this.isPaused = false;

    try {
      // 1. 初始化上传，获取文件ID
      const initResponse = await this.initUpload();
      this.fileId = initResponse.data.fileId;

      // 2. 按顺序上传所有分片
      while (this.currentChunk < this.totalChunks && !this.isPaused) {
        await this.uploadChunk();
        this.currentChunk++;
      }

      if (!this.isPaused) {
        // 3. 完成上传
        await this.completeUpload();
        this.options.onSuccess?.({
          fileId: this.fileId,
          fileName: this.file.name,
          fileSize: this.file.size
        });
      }
    } catch (error) {
      this.options.onError?.(error as Error);
    } finally {
      this.isUploading = false;
    }
  }

  // 暂停上传
  pauseUpload(): void {
    this.isPaused = true;
  }

  // 继续上传
  resumeUpload(): void {
    if (this.isPaused) {
      this.isPaused = false;
      this.startUpload();
    }
  }

  // 取消上传
  cancelUpload(): void {
    this.isPaused = true;
    this.isUploading = false;
    this.currentChunk = 0;
  }

  // 初始化上传
  private async initUpload() {
    return axios.post('/api/upload/init', {
      fileName: this.file.name,
      fileSize: this.file.size,
      totalChunks: this.totalChunks
    });
  }

  // 上传分片
  private async uploadChunk() {
    const start = this.currentChunk * this.chunkSize;
    const end = Math.min(start + this.chunkSize, this.file.size);
    const chunk = this.file.slice(start, end);

    const formData = new FormData();
    formData.append('file', chunk);
    formData.append('fileId', this.fileId);
    formData.append('chunkIndex', this.currentChunk.toString());
    formData.append('totalChunks', this.totalChunks.toString());

    const response = await axios.post('/api/upload/chunk', formData, {
      onUploadProgress: (progressEvent) => {
        if (progressEvent.total) {
          const loaded = this.currentChunk * this.chunkSize + progressEvent.loaded;
          const total = this.file.size;
          const percentage = Math.round((loaded / total) * 100);
          
          this.options.onProgress?.({
            loaded,
            total,
            percentage
          });
        }
      }
    });

    return response;
  }

  // 完成上传
  private async completeUpload() {
    return axios.post('/api/upload/complete', {
      fileId: this.fileId,
      fileName: this.file.name,
      totalChunks: this.totalChunks
    });
  }
} 